package com.exploadingelephants.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.LinkedList;
import java.util.List;

import android.content.Context;
import android.os.Environment;
import ch.exploadingelephants.model.Level;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;

/**
 * @author Sandro De Zanet
 * 
 */
public class LevelIO {
    /**
     * @param context
     * @param level
     * @throws FileNotFoundException
     */
    public static void storeLevel(Context context, Level level)
	    throws FileNotFoundException {
	if (isAppropriateToReadWrite()) {
	    File externalFilesDir = context.getExternalFilesDir(null);
	    if (externalFilesDir != null) {
		File file = new File(externalFilesDir.getAbsolutePath()
			+ File.separator + level.getIdentifier() + ".game");

		Kryo kryo = new Kryo();
		FileOutputStream outputStream = new FileOutputStream(
			file.getAbsolutePath());
		Output output = new Output(outputStream);
		kryo.writeObject(output, level);
		output.close();
	    }
	}
    }

    /**
     * @param id
     * @return
     * @throws FileNotFoundException
     */
    public static Level loadLevelByFilename(Context context, String filename)
	    throws FileNotFoundException {
	Kryo kryo = new Kryo();
	FileInputStream inputStream = new FileInputStream(filename);
	Input input = new Input(inputStream);
	Level level = kryo.readObject(input, Level.class);
	input.close();
	return level;
    }

    /**
     * @return
     * 
     */
    public static List<Level> loadAllLevels(Context context) {
	List<Level> levels = new LinkedList<Level>();
	if (isAppropriateToReadWrite()) {
	    File externalFilesDir = context.getExternalFilesDir(null);
	    if (externalFilesDir != null) {
		String[] list = externalFilesDir.list(null);
		for (String filename : list) {
		    try {
			Level level = loadLevelByFilename(context,
				externalFilesDir.getAbsolutePath()
					+ externalFilesDir.separator + filename);
			levels.add(level);
		    } catch (FileNotFoundException e) {
			e.printStackTrace();
		    }
		}
	    }
	}
	return levels;
    }

    /**
     * @return
     */
    private static boolean isAppropriateToReadWrite() {
	boolean mExternalStorageAvailable = false;
	boolean mExternalStorageWriteable = false;
	String state = Environment.getExternalStorageState();

	if (Environment.MEDIA_MOUNTED.equals(state)) {
	    // We can read and write the media
	    mExternalStorageAvailable = mExternalStorageWriteable = true;
	} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
	    // We can only read the media
	    mExternalStorageAvailable = true;
	    mExternalStorageWriteable = false;
	} else {
	    // Something else is wrong. It may be one of many other states,
	    // but all we need
	    // to know is we can neither read nor write
	    mExternalStorageAvailable = mExternalStorageWriteable = false;
	}
	return mExternalStorageAvailable && mExternalStorageWriteable;
    }
}
